博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
权限组件(2):二级菜单
阅读量:6154 次
发布时间:2019-06-21

本文共 5210 字,大约阅读时间需要 17 分钟。

二级菜单效果图

 

一、把一级菜单从权限表里抽离出来,单独创建一个表

rbac/models

Menu

class Menu(models.Model):    """    菜单表    """    title = models.CharField(verbose_name='一级菜单的名称', max_length=32)    icon = models.CharField(verbose_name='图标', max_length=32, null=True, blank=True)    def __str__(self):        return self.title

 

Permission

class Permission(models.Model):    """    权限表    """    title = models.CharField(verbose_name='标题', max_length=32)    url = models.CharField(verbose_name='含正则的URL', max_length=128)    menu = models.ForeignKey(verbose_name='所属菜单', to=Menu, null=True, blank=True,                             help_text='null表示不是菜单,非null表示是二级菜单', on_delete=models.CASCADE                             )    def __str__(self):        return self.title

 

 

二、修改初始化权限

rbac/service/init_permission.py

思路:

  1. 获取一级菜单和二级菜单的信息
  2. 找出有menu_id的菜单(可以做二级菜单的)
  3. 将一级菜单的id作为key,values还是一个字典,里面储存一级菜单的标题、图标和二级菜单。

 代码:

from permission_learn import settingsdef init_permission(current_user, request):    """    用户权限的初始化    :param current_user:  当前登录用户    :param request:    :return:    """    permission_menu_queryset = current_user.roles.filter(permissions__isnull=False).values(        'permissions__id',        'permissions__title',        'permissions__url',        'permissions__menu_id',  # +        'permissions__menu__title',  # +        'permissions__menu__icon',  # +    ).distinct()    menu_dict = {}    permission_list = []    for item in permission_menu_queryset:        permission_list.append(item['permissions__url'])        menu_id = item['permissions__menu_id']        if not menu_id:            continue        second_menu = {
'title': item['permissions__title'], 'url': item['permissions__url']} if menu_id in menu_dict: menu_dict[menu_id]['second_menu'].append(second_menu) else: menu_dict[menu_id] = { 'title': item['permissions__menu__title'], 'icon': item['permissions__menu__icon'], 'second_menu': [second_menu, ] } request.session[settings.PERMISSION_SESSION_KEY] = permission_list request.session[settings.MENU_SESSION_KEY] = menu_dict"""客户列表 /customer/list/ 1 ForeignKey --> 1 客户管理 fa-hdd-o 添加客户 /customer/add/ null 编辑客户 /customer/edit/(?P
\d+)/ null 删除客户 /customer/del/(?P
\d+)/ null"""

 

 

三、渲染到模板

rbac/templatetags/rbac.py

import refrom collections import OrderedDictfrom django.conf import settingsfrom django.template import Libraryregister = Library()@register.inclusion_tag('rbac/multi_menu.html')def multi_menu(request):    menu_dict = request.session[settings.MENU_SESSION_KEY]    # 对字典的key进行排序。得到的结果是只包含Key的列表,类似这样的 [1,2,3]    key_list = sorted(menu_dict)    # 空的有序字典    ordered_dict = OrderedDict()  # 有序字典,按照我们想要的顺序展示    current_path = request.path    for key in key_list:        menu = menu_dict[key]  # {'title':'客户管理','icon':'fa fa-book','second_menu':[二级菜单1,二级菜单2,...]}        menu['class'] = 'hide'  # 隐藏二级菜单        for second_menu in menu['second_menu']:            regex = '^%s$' % second_menu['url']            if re.match(regex, current_path):                second_menu['class'] = 'active'                menu['class'] = ''  # 显示点中的二级菜单        ordered_dict[key] = menu    context = {        'menus': ordered_dict    }    return context

 

 

需要注意的是对字典的key进行排序得到的结果是只包含Key的列表,menu_dict的key是menu_id,最后得到这样的 [1,2,3...]的结果

通过templatestag渲染二级菜单到模板:rbac/templates/rbac/multi_menu.html

{% for menu in menus.values %}
{
{ menu.title }}
{% endfor %}

 

layout.html页面只需要把一级菜单的templates替换成二级菜单的就行

-       {% menu request %}    +       {% multi_menu request %}

 

js代码:rbac/static/rbac/js/rbac.js

$('.multi-menu .title').click(function () {    $(this).next().toggleClass('hide');});

toggleClass检查每个元素中指定的类。如果不存在则添加类,如果已设置则删除之。这就是所谓的切换效果。

 

css代码:rbac/static/rbac/css/rbac.css

'''.multi-menu .item {}.multi-menu .item > .title {
padding: 10px 5px;border-bottom: 1px solid #dddddd;cursor: pointer;color: #333;display: block;background: #efefef;background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #efefef), color-stop(1, #fafafa));background: -ms-linear-gradient(bottom, #efefef, #fafafa);background: -o-linear-gradient(bottom, #efefef, #fafafa);filter: progid:dximagetransform.microsoft.gradient(startColorStr='#e3e3e3', EndColorStr='#ffffff');-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa',EndColorStr='#efefef')";box-shadow: inset 0 1px 1px white;}.multi-menu .item > .body {
border-bottom: 1px solid #dddddd;}.multi-menu .item > .body a {
display: block;padding: 5px 20px;text-decoration: none;border-left: 2px solid transparent;font-size: 13px;}.multi-menu .item > .body a:hover {
border-left: 2px solid #2F72AB;}.multi-menu .item > .body a.active {
border-left: 2px solid #2F72AB;}'''

 

中间件不需要改动

 

转载于:https://www.cnblogs.com/lshedward/p/10494653.html

你可能感兴趣的文章
清除(设置)CCS5.5 eclipse的workspace记录
查看>>
Coach Handbags - generating modifications devoid of any altering In Style
查看>>
【转载】wp7屏幕截图代码
查看>>
Object-C非正式协议与正式协议的区别
查看>>
day18-python的正则表达式
查看>>
18-angular.isObject
查看>>
android Launcher——拖放功能深入研究
查看>>
mysql union (all) 后order by的排序失效问题解决
查看>>
JQ元素选择器
查看>>
Java集合框架源码(二)——hashSet
查看>>
samba后台进程及安全模式简介
查看>>
怎样使用Phonegap Build工具云编译ionic项目
查看>>
jmeter 正则表达式 练习
查看>>
css与html结合四种方式
查看>>
数据结构:二级指针与不含表头的单链表
查看>>
自定义一个compass可编译的目录结构
查看>>
java中为什么要单继承,多实现
查看>>
在 Laravel 中通过 Artisan View 扩展包创建及删除应用视图文件
查看>>
精简自己20%的代码(异常的处理)
查看>>
运维自动化工具 Cobbler
查看>>